﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Reflection;
using System.IO;
using GameEngine;
using System.Windows.Controls.Ribbon;
using Daphne.Presenters;

using ComputerEngine;
using System.Windows.Controls.Primitives;
using Tomers.WPF.Localization;
using System.Globalization;
using MHWrap = Daphne.MoveHelperWrapper;


namespace Daphne
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : RibbonWindow
    {
        private eGameType _GameType = eGameType.OnePlayer;

        private const string sPicturePath = "AppData/Pictures";
        private const string _sOpeningPath = "AppData\\Opening";
        private const string _sEndGamePath = "AppDAta\\EndGame";
        private const int _iEndGameCacheSizeInMB = 256;
        private DaphneConfig _daphneConfig = null;
        private const string _sDaphneConfigKey = "DaphneConfig";

        private MHWrap.GameStateConfig _gameStateConfig = null;
        private GameManager _mng;
        private ProfessionalGameBoardPresenter _presenter;
        private Engine _engine;
        private string _sAppPath;
        private Board3D.eBoardView _currentView = Board3D.eBoardView.FromTop;

        private RecentFileList _recentFileList;       

        public MainWindow()
        {
            InitializeComponent();
            this.Loaded += new RoutedEventHandler(MainWindow_Loaded);
            string sAppPath = Assembly.GetExecutingAssembly().Location;
            sAppPath = System.IO.Path.GetDirectoryName(sAppPath);
            _sAppPath = sAppPath;

            _mng = GameManagerFactory.CreateGameManager(enumGameType.Czech);
            _mng.GameBoard.SetupStartPosition(3);
          
            string sImagePath = System.IO.Path.Combine(sAppPath, sPicturePath);

            _presenter = new ProfessionalGameBoardPresenter();
            _presenter.GameManager = _mng;
            uxBoard2D.SetPresenter(_presenter);
            uxBoard2D.LoadImages(sImagePath);
            _presenter.MoveDoneEvent += new TMoveDoneDelegate(_presenter_MoveDoneEvent);
            _presenter.AnimationMoveFinishedEvent += new EventHandler(_presenter_AnimationMoveFinishedEvent);
            _presenter.ShowNumberCoordinates = false;

            uxFigureCountCtrl.GameManager = _mng;
            uxOnMove.SetData(sAppPath, _mng);
            //uxMasterTab.SetGameManager(_mng);
            uxGameList.GameManager = _mng;
            //uxMasterTab.MoveSetEvent += uxMasterTab_MoveSetEvent;
            uxGameList.MoveSetEvent += uxGameList_MoveSetEvent;
            uxGameList.NotationChangedEvent += uxGameList_NotationChangedEvent;

            _engine = new Engine();
            _engine.BackgroundProcessInit += new EventHandler<BackgroundProcessEventArgs>(_engine_BackgroundProcessInit);
            _engine.ProgressReport += new EventHandler<ProgressReportEventArgs>(_engine_ProgressReport);
            _engine.BackgroundProcessFinished += new EventHandler(_engine_BackgroundProcessFinished);
            _engine.MoveComputed += _engine_MoveComputed;
            

            string sCompleteOpeningPath = System.IO.Path.Combine(sAppPath, _sOpeningPath);
            if(_engine.LoadOpeningDatabase(sCompleteOpeningPath) == false)
            {
                MessageBox.Show(GetTextValue("APP_ErrorOpeningDB"), GetTextValue("APP_Error"), 
                        MessageBoxButton.OK, MessageBoxImage.Error);
            }


            // try to load global settings
            _daphneConfig = Config.Get<DaphneConfig>(_sDaphneConfigKey);
            if (_daphneConfig == null)
            {
                // if not loaded, create default settings
                _daphneConfig = new DaphneConfig();

                // if no config set, ask for language
                AskForLanguage(false);
            }
            else
            {
                // set the saved locale type
                LanguageContext.Instance.Culture = CultureInfo.GetCultureInfo(_daphneConfig.LangCode);
            }


            // set the settings
            SwitchBoard(_daphneConfig.BoardType);
            _iEngineLevel = _daphneConfig.ComputerLevel;


            uxGameStatus.UpdateStatus(eGameType.OnePlayer, enumGameResult.Unknown, _iEngineLevel);
            this.GameUpdate();
            InitStatusBar();

            SetTheme(_daphneConfig.Theme);

            uxRibbonAppMenu.DropDownOpened += uxRibbonAppMenu_DropDownOpened;

            // init recent file list
            _recentFileList = new RecentFileList();
            _recentFileList.UseRegistryPersister("Daphne2013");
            _recentFileList.MaxNumberOfFiles = 15;
            uxRecentFileList.RecentFileList = _recentFileList;
        }

        void uxGameList_NotationChangedEvent(object sender, Controls.NotationChangedArgs e)
        {
            _presenter.ShowNumberCoordinates = e.NumberNotationOn;
            uxBoard2D.Refresh();
        }

        void uxRibbonAppMenu_DropDownOpened(object sender, EventArgs e)
        {
            uxLevel1.IsChecked = false;
            uxLevel2.IsChecked = false;
            uxLevel3.IsChecked = false;
            uxLevel4.IsChecked = false;
            uxLevel5.IsChecked = false;

            uxGraphLevel1.IsChecked = false;
            uxGraphLevel2.IsChecked = false;
            uxGraphLevel3.IsChecked = false;
            uxGraphLevel4.IsChecked = false;

            switch (_iEngineLevel)
            {
                case 1:
                    uxLevel1.IsChecked = true;
                    break;
                case 2:
                    uxLevel2.IsChecked = true;
                    break;
                case 3:
                    uxLevel3.IsChecked = true;
                    break;
                case 4:
                    uxLevel4.IsChecked = true;
                    break;
                case 5:
                    uxLevel5.IsChecked = true;
                    break;
            }

            //switch (uxBoard3D.GetGraphicsLevel())
            //{
            //    case 1:
            //        uxGraphLevel1.IsChecked = true;
            //        break;
            //    case 2:
            //        uxGraphLevel2.IsChecked = true;
            //        break;
            //    case 3:
            //        uxGraphLevel3.IsChecked = true;
            //        break;
            //    case 4:
            //        uxGraphLevel4.IsChecked = true;
            //        break;
            //}
        }


        void MainWindow_Loaded(object sender, RoutedEventArgs e)
        {
            double height = uxRibbon.ActualHeight;
            uxRibbonRow.Height = new GridLength(height, GridUnitType.Pixel);

            ReplaceRibbonApplicationMenuButtonContent(uxRibbonAppMenu);

            string sPath = System.IO.Path.Combine(_sAppPath, _sEndGamePath);

            UpdateWindowTitle();

            if (_engine != null)
                _engine.PreloadEndgameDatabase(sPath, _iEndGameCacheSizeInMB);

            uxBoard3D.LoadModels(_sAppPath, Board3D.Models.enumBoardStyle.Classic);
            uxBoard3D.SetGameManager(_mng);
            uxBoard3D.AnimatingMoveFinished += new EventHandler(_presenter_AnimationMoveFinishedEvent);
            uxBoard3D.MoveDoneEvent += uxBoard3D_MoveDoneEvent;


            Set3DView(_daphneConfig.Board3DView);
            SetGraphicsLevel(_daphneConfig.GraphicsLevel);
        }

        private void UpdateWindowTitle()
        {
            // set program version
            string sVersion = Assembly.GetEntryAssembly().GetName().Version.ToString();
            this.Title = GetTextValue("APP_AppVersion") + sVersion;
        }

        //protected override void OnRenderSizeChanged(SizeChangedInfo sizeInfo)
        //{
        //    uxBoardRow.Height = new GridLength(uxBoardCol.ActualWidth, GridUnitType.Pixel);
        //    base.OnRenderSizeChanged(sizeInfo);
        //}

        protected override void OnClosing(System.ComponentModel.CancelEventArgs e)
        {
            // terminate computer
            if (_engine != null)
                _engine.TerminateComputer();

            // save settings
            Config.Set<DaphneConfig>(_sDaphneConfigKey, _daphneConfig);

            base.OnClosing(e);
        }


        void ReplaceRibbonToggleButtonContent(RibbonToggleButton toggleButton, string text)
        {
            // Subdues the aero highlighting to that the text has better contrast.
            Grid grid = (Grid)VisualTreeHelper.GetChild(toggleButton, 0);
            Border middleBorder = (Border)grid.Children[1];
            middleBorder.Opacity = .5;

            // Replaces the images with the label text.
            StackPanel stackPanel = (StackPanel)grid.Children[2];
            UIElementCollection children = stackPanel.Children;
            children.RemoveRange(0, children.Count);
            TextBlock textBlock = new TextBlock(new Run(text));
            textBlock.Foreground = Brushes.White;
            children.Add(textBlock);
        }

        void ReplaceRibbonApplicationMenuButtonContent(RibbonApplicationMenu menu)
        {
            Grid outerGrid = (Grid)VisualTreeHelper.GetChild(menu, 0);
            RibbonToggleButton toggleButton = (RibbonToggleButton)outerGrid.Children[0];
            ReplaceRibbonToggleButtonContent(toggleButton, menu.Label);

            Popup popup = (Popup)outerGrid.Children[2];
            EventHandler popupOpenedHandler = null;
            popupOpenedHandler = new EventHandler(delegate
            {
                Decorator decorator = (Decorator)popup.Child;
                Grid popupGrid = (Grid)decorator.Child;
                Canvas canvas = (Canvas)popupGrid.Children[1];
                RibbonToggleButton popupToggleButton = (RibbonToggleButton)canvas.Children[0];
                ReplaceRibbonToggleButtonContent(popupToggleButton, menu.Label);
                popup.Opened -= popupOpenedHandler;
            });
            popup.Opened += popupOpenedHandler;
        }

    }
}
